package common.util.media;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;

import org.imgscalr.Scalr;
import org.springframework.util.StringUtils;

import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.Global;
import common.Constant;
import common.util.SystemProperties;
import domain.Resolution;

public class VideoUtil {
	private static int mVideoStreamIndex = -1;
	private static long mLastPtsWrite = Global.NO_PTS;
	public static final double SECONDS_BETWEEN_FRAMES = 10;
	private static boolean continueFlat = true;

	public static final long MICRO_SECONDS_BETWEEN_FRAMES = (long) (Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES);

	static public String saveOriginalFile(InputStream inputStream, String name,
			String originalFilename) throws IOException {
		String extension = getExtension(originalFilename);

		StringBuffer url = new StringBuffer();
		url.append(SystemProperties.getProperty(Constant.PROPERTIES_NAME.DIRECTORY.VIDEO_PRE))
				.append(SystemProperties.getProperty(Constant.PROPERTIES_NAME.DIRECTORY.SUB_URL.VIDEO.ORIGINAL))
				.append(name).append(".").append(extension);

		File newFile = new File(url.toString());
		OutputStream outputStream = new FileOutputStream(newFile);
		
		int read = 0;
		byte[] bytes = new byte[1024];
 
		while ((read = inputStream.read(bytes)) != -1) {
			outputStream.write(bytes, 0, read);
		}
		
		outputStream.close();
		
		return url.toString();
	}

	public static String getExtension(File file) {
		return getExtension(file.getName());
	}

	public static String getExtension(String fileName) {
		String extension = "";

		int i = fileName.lastIndexOf('.');
		if (i > 0) {
			extension = fileName.substring(i + 1);
		}
		return extension;
	}
	
	public static void createThumbnailImage(String inputFileUrl, String newName) {
		
		Boolean  isContinue = true;

        IMediaReader mediaReader = ToolFactory.makeReader(inputFileUrl);

        // stipulate that we want BufferedImages created in BGR 24bit color space
        mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
        
        mediaReader.addListener(new ImageSnapListener(newName));

        // read out the contents of the media file and
        // dispatch events to the attached listener
        while (continueFlat && mediaReader.readPacket() == null) ;
        continueFlat = true;
        mediaReader.close();

    }
	public static void main(String[] args) {
		createThumbnailImage("C:/Users/hung/Favorites/Desktop/video/test1.m4v", "test");
	}

	private static class ImageSnapListener extends MediaListenerAdapter {
		private String imageName ;
		private boolean isCapture = false;
		
		public boolean isCapture() {
			return isCapture;
		}

		public void setCapture(boolean isCapture) {
			this.isCapture = isCapture;
		}

		public String getImageName() {
			return imageName;
		}

		public void setImageName(String imageName) {
			this.imageName = imageName;
		}

		public ImageSnapListener(String name){
			super();
			this.setImageName(name);
		}
		
        public void onVideoPicture(IVideoPictureEvent event) {
        	if (this.isCapture()) return;

            /*if (event.getStreamIndex() != mVideoStreamIndex) {
                // if the selected video stream id is not yet set, go ahead an
                // select this lucky video stream
                if (mVideoStreamIndex == -1)
                    mVideoStreamIndex = event.getStreamIndex();
                // no need to show frames from this video stream
                else
                    return;
            }

            // if uninitialized, back date mLastPtsWrite to get the very first frame
            if (mLastPtsWrite == Global.NO_PTS)
                mLastPtsWrite = event.getTimeStamp() - MICRO_SECONDS_BETWEEN_FRAMES;*/

            // if it's time to write the next frame
            /*if (event.getTimeStamp() - mLastPtsWrite >= 
                    MICRO_SECONDS_BETWEEN_FRAMES) {
                                
                String outputFilename = dumpImageToFile(event.getImage(),this.getImageName());

                // indicate file written
                double seconds = ((double) event.getTimeStamp()) /  Global.DEFAULT_PTS_PER_SECOND;
                
                System.out.printf(  "at elapsed time of %6.3f seconds wrote: %s\n",seconds, outputFilename);

                // update last write time
                mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES;
            }
*/
            if (event.getTimeStamp() >= 2000000) {
                                
                dumpImageToFile(event.getImage(),this.getImageName());
                continueFlat = false;
                // update last write time
                /*mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES;*/
            }
        }
        
        private String dumpImageToFile(BufferedImage image, String name) {
        	String extension = SystemProperties
    				.getProperty(Constant.PROPERTIES_NAME.FILE_EXTENTION.THUMBNAIL);
    		Resolution resol = new Resolution();
    		resol.setHeight(100);
    		resol.setWeight(100);

    		StringBuffer url = new StringBuffer();
    		url.append(	SystemProperties.getProperty(Constant.PROPERTIES_NAME.DIRECTORY.IMAGE_PRE))
    				.append(SystemProperties.getProperty(Constant.PROPERTIES_NAME.DIRECTORY.SUB_URL.IMAGE.THUMB))
    				.append(name).append(".").append(extension);
    		BufferedImage newImage =Scalr.resize(image, Scalr.Method.QUALITY, Scalr.Mode.FIT_TO_WIDTH,
    				resol.getWeight(),resol.getHeight(), Scalr.OP_ANTIALIAS);
    		try {
				ImageIO.write(newImage, extension, new File(url.toString()));
				this.setCapture(true);
				return url.toString();
				
			} catch (IOException e) {
				e.printStackTrace();
				return null;
			}
    		
        }

    }
}
